import axios, { AxiosInstance, AxiosRequestConfig } from "axios"

export default class Api {
  instance: AxiosInstance
  config: AxiosRequestConfig
  interceptor?: Interceptor
  loading: boolean

  constructor(option: ApiType) {
    this.config = option
    this.interceptor = option.interceptor
    this.loading = option.loading ?? true
    this.instance = axios.create(this.config)
    this.instance.interceptors.request.use(this.interceptor?.requestInterceptor, this.interceptor?.requestInterceptorErr)
    this.instance.interceptors.response.use(this.interceptor?.responseInterceptor, this.interceptor?.responseInterceptorErr)
  }

  request<T>(config: AxiosRequestConfig<T>): Promise<T> {
    return this.instance.request(config)
  }

  get<T>(uri: string, data?: object): Promise<T> {
    return this.instance.get(uri, {
      params: data || {},
    })
  }

  post<T>(uri: string, data?: object): Promise<T> {
    return this.instance.post(uri, data)
  }

  postJSON<T>(uri: string, data?: object): Promise<T> {
    return this.instance.post(uri, data || {}, {
      headers: {
        "Content-Type": "application/json",
      },
    })
  }

  put<T>(uri: string, data?: object): Promise<T> {
    return this.instance.put(uri, data, {
      data: data || {},
    })
  }

  delete<T>(uri: string, data?: object): Promise<T> {
    return this.instance.delete(uri, {
      data: data || {},
    })
  }
}

export interface ApiType extends AxiosRequestConfig {
  loading?: boolean
  interceptor?: Interceptor
}

export interface Interceptor {
  requestInterceptor: (res: AxiosRequestConfig) => AxiosRequestConfig
  requestInterceptorErr?: (err: any) => any
  responseInterceptor: (res: AxiosRequestConfig) => AxiosRequestConfig
  responseInterceptorErr?: (err: any) => any
}
